home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / util / arc / PPCUnACE.lha / PPCUnACE / source.lha / Src / Unace.c < prev    next >
C/C++ Source or Header  |  1997-12-10  |  16KB  |  573 lines

  1. /* ------------------------------------------------------------------------ */
  2. /*                                                                          */
  3. /*      Main file of public UNACE.                                          */
  4. /*                                                                          */
  5. /* ------------------------------------------------------------------------ */
  6.  
  7.  
  8. //--------------- include general files ------------------------------------//
  9. #include <ctype.h>      // tolower()
  10. #include <fcntl.h>      // open()
  11. #include <stdio.h>      // printf() sprintf() remove()
  12. #include <stdlib.h>     // malloc()
  13. #include <string.h>     // str*()
  14. #include <sys/stat.h>   // S_I*  AMIGA: fstat()
  15.  
  16. #if defined(AMIGA)
  17.  #include <error.h>     // errno
  18.  #include <proto/dos.h>
  19. #endif
  20. #if defined(DOS) || defined(WIN32) || defined(WIN16)
  21.  #include <io.h>       // lseek() open() read() write() eof() tell() close()
  22. #if defined(WATCOM_C) 
  23.  #include <dos.h>      // lseek() open() read() write() eof() tell() close()
  24. #endif
  25. #endif
  26.  
  27.  
  28. //--------------- include unace specific header files ----------------------//
  29. #include "os.h"
  30.  
  31. #include "globals.h"
  32. #include "portable.h"
  33. #include "uac_comm.h"
  34. #include "uac_crc.h"
  35. #include "uac_crt.h"
  36. #include "uac_dcpr.h"
  37. #include "uac_sys.h"
  38.  
  39. #ifdef CRYPT
  40.  #include "unace_ps.h"
  41. #endif /* CRYPT */
  42.  
  43.  
  44. //--------------- BEGIN OF UNACE ROUTINES ----------------------------------//
  45.  
  46. void init_unace(void)           // initializes unace
  47. {
  48.    buf_rd =malloc(size_rdb * sizeof(ULONG));  // Allocate buffers: increase
  49.    buf    =malloc(size_buf);                  // sizes when possible to speed
  50.    buf_wr =malloc(size_wrb);                  // up the program
  51.    readbuf=malloc(size_headrdb);
  52.  
  53.    if (buf_rd ==NULL ||
  54.        buf    ==NULL ||
  55.        buf_wr ==NULL ||
  56.        readbuf==NULL )
  57.       f_err = ERR_MEM;
  58.  
  59.    make_crctable();             // initialize CRC table
  60.    dcpr_init();                 // initialize decompression
  61.  
  62.    set_handler();               // ctrl+break etc.
  63. }
  64.  
  65. void done_unace(void)
  66. {
  67.    if (buf_rd   ) free(buf_rd   );
  68.    if (buf      ) free(buf      );
  69.    if (buf_wr   ) free(buf_wr   );
  70.    if (readbuf  ) free(readbuf  );
  71.    if (dcpr_text) free(dcpr_text);
  72. }
  73.  
  74. INT  read_header(INT print_err)         // reads any header from archive
  75. {
  76.    USHORT rd,
  77.         head_size,
  78.         crc_ok;
  79.    LONG crc;
  80.    UCHAR *tp=readbuf;
  81.  
  82.    lseek(archan, skipsize, SEEK_CUR);   // skip ADDSIZE block
  83.  
  84.    if (read(archan, &head, 4)<4)
  85.       return (0);                       // read CRC and header size
  86.  
  87. #ifdef HI_LO_BYTE_ORDER
  88.    WORDswap(&head.HEAD_CRC);
  89.    WORDswap(&head.HEAD_SIZE);
  90. #endif
  91.                                         // read size_headrdb bytes into 
  92.    head_size = head.HEAD_SIZE;          // header structure 
  93.    rd = (head_size > size_headrdb) ? size_headrdb : head_size;
  94.    if (read(archan, readbuf, rd) < rd)
  95.       return (0);
  96.    head_size -= rd;
  97.    crc = getcrc(CRC_MASK, readbuf, rd);
  98.  
  99.    while (head_size)                    // skip rest of header
  100.    {                            
  101.       rd = (head_size > size_buf) ? size_buf : head_size;
  102.       if (read(archan, buf, rd) < rd)
  103.          return (0);
  104.       head_size -= rd;
  105.       crc = getcrc(crc, buf, rd);
  106.    }
  107.  
  108.    head.HEAD_TYPE =*tp++;               // generic buffer to head conversion
  109.    head.HEAD_FLAGS=BUFP2WORD(tp);
  110.  
  111.    if (head.HEAD_FLAGS & ACE_ADDSIZE)
  112.       skipsize = head.ADDSIZE = BUF2LONG(tp);   // get ADDSIZE
  113.    else
  114.       skipsize = 0;
  115.  
  116.                                                 // check header CRC 
  117.    if (!(crc_ok = head.HEAD_CRC == (crc & 0xffff)) && print_err)
  118.       printf("\nError: archive is broken\n");
  119.    else
  120.    switch (head.HEAD_TYPE)              // specific buffer to head conversion
  121.    {
  122.       case MAIN_BLK:
  123.          memcpy(mhead.ACESIGN, tp, acesign_len); tp+=acesign_len;
  124.          mhead.VER_MOD=*tp++;
  125.          mhead.VER_CR =*tp++;
  126.          mhead.HOST_CR=*tp++;
  127.          mhead.VOL_NUM=*tp++;
  128.          mhead.TIME_CR=BUFP2LONG(tp);
  129.          mhead.RES1   =BUFP2WORD(tp);
  130.          mhead.RES2   =BUFP2WORD(tp);
  131.          mhead.RES    =BUFP2LONG(tp);
  132.          mhead.AV_SIZE=*tp++;
  133.          memcpy(mhead.AV, tp, rd-(USHORT)(tp-readbuf));
  134.          break;
  135.       case FILE_BLK:
  136.          fhead.PSIZE     =BUFP2LONG(tp);
  137.          fhead.SIZE      =BUFP2LONG(tp);
  138.          fhead.FTIME     =BUFP2LONG(tp);
  139.          fhead.ATTR      =BUFP2LONG(tp);
  140.          fhead.CRC32     =BUFP2LONG(tp);
  141.          fhead.TECH.TYPE =*tp++;
  142.          fhead.TECH.QUAL =*tp++;
  143.          fhead.TECH.PARM =BUFP2WORD(tp);
  144.          fhead.RESERVED  =BUFP2WORD(tp);
  145.          fhead.FNAME_SIZE=BUFP2WORD(tp);
  146.          memcpy(fhead.FNAME, tp, rd-(USHORT)(tp-readbuf));
  147.          break;
  148. //    default: (REC_BLK and future things): 
  149. //              do nothing 'cause isn't needed for extraction
  150.    }
  151.  
  152.    return (crc_ok);
  153. }
  154.                                 // maximum SFX module size 
  155. #define max_sfx_size 65536      // (needed by read_arc_head)
  156.  
  157. INT read_arc_head(void)         // searches for the archive header and reads it
  158. {
  159.    INT  i,
  160.         flags,
  161.         buf_pos = 0;
  162.    LONG arc_head_pos,
  163.         old_fpos,
  164.         fpos = 0;
  165.    struct stat st;
  166.  
  167.    fstat(archan, &st);
  168.  
  169.    memset(buf, 0, size_buf);
  170.  
  171.    while (tell(archan)<st.st_size && fpos < max_sfx_size)
  172.    {
  173.       old_fpos = fpos;
  174.       fpos += read(archan, &buf[buf_pos], size_buf - buf_pos);
  175.  
  176.       for (i = 0; i < size_buf; i++)    // look for the acesign
  177.       {                         
  178.          if (!memcmp(acesign, &buf[i], acesign_len))
  179.          {             
  180.                                         // seek to the probable begin 
  181.                                         // of the archive
  182.             arc_head_pos = old_fpos + i - buf_pos -  bytes_before_acesign;
  183.             lseek(archan, arc_head_pos, SEEK_SET);
  184.             if (read_header(0))         // try to read archive header
  185.             {                           
  186.                flags = mhead.HEAD_FLAGS;
  187.                adat.sol     = (flags & ACE_SOLID) > 0;
  188.                adat.vol     = (flags & ACE_MULT_VOL) > 0;
  189.                adat.vol_num = mhead.VOL_NUM;
  190.                adat.time_cr = mhead.TIME_CR;
  191.                return (1);
  192.             }
  193.          }
  194.       }
  195.                                         // was no archive header,
  196.                                         // continue search
  197.       lseek(archan, fpos, SEEK_SET);
  198.       memcpy(buf, &buf[size_buf - 512], 512);
  199.       buf_pos = 512;                    // keep 512 old bytes
  200.    }
  201.    return (0);
  202. }
  203.  
  204. INT  open_archive(INT print_err)        // opens archive (or volume)
  205. {
  206.    CHAR av_str[80];
  207.  
  208.    archan = open(aname, O_RDONLY | O_BINARY);   // open file
  209.  
  210.    if (archan == -1)
  211.    {
  212.       printf("\nError opening file %s", aname);
  213.       return (0);
  214.    }
  215.    if (!read_arc_head())                        // read archive header
  216.    {                            
  217.       if (print_err)
  218.          printf("\nInvalid archive file: %s\n", aname);
  219.       close(archan);
  220.       return (0);
  221.    }
  222.  
  223.    printf("\nProcessing archive: %s\n\n", aname);
  224.    if (head.HEAD_FLAGS & ACE_AV)
  225.    {
  226.       printf("Authenticity Verification:");   // print the AV
  227.       sprintf(av_str, "\ncreated on %d.%d.%d by ",
  228.               ts_day(adat.time_cr), ts_month(adat.time_cr), ts_year(adat.time_cr));
  229.       printf(av_str);
  230.       strncpy(av_str, mhead.AV, mhead.AV_SIZE);
  231.       av_str[mhead.AV_SIZE] = 0;
  232.       printf("%s\n\n", av_str);
  233.    }
  234.    comment_out("Main comment:");        // print main comment
  235.    return (1);
  236. }
  237.  
  238. void get_next_volname(void)             // get file name of next volume
  239. {
  240.    CHAR *cp;
  241.    INT  num;
  242.  
  243.    if ((cp = (CHAR *) strrchr(aname, '.')) == NULL || !*(cp + 1))
  244.       num = -1;
  245.    else
  246.    {
  247.       cp++;
  248.       num = (*(cp + 1) - '0') * 10 + *(cp + 2) - '0';
  249.       if (!in(num, 0, 99))
  250.          num = -1;
  251.       if (in(*cp, '0', '9'))
  252.          num += (*cp - '0') * 100;
  253.    }
  254.    num++;
  255.  
  256.    if (num < 100)
  257.       *cp = 'C';
  258.    else
  259.       *cp = num / 100 + '0';
  260.    *(cp + 1) = (num / 10) % 10 + '0';
  261.    *(cp + 2) = num % 10 + '0';
  262. }
  263.  
  264. INT  proc_vol(void)                     // opens volume
  265. {
  266.    INT  i;
  267.    CHAR s[80];
  268.  
  269.    if (!fileexists(aname) || !f_allvol_pr)
  270.    {
  271.       do
  272.       {
  273.          sprintf(s,